import fs from "node:fs/promises";
import path from "node:path";
import { RunnerSpec, TaskHandler } from "../types";
import { resolvePath, ensureDir } from "../utils";
import { loadStructuredData } from "../../../tools/data-processor";

async function loadMinifier() {
  const minifierPath = path.join(
    path.resolve(__dirname, "..", "..", ".."),
    "Figma-Context-MCP-DIY",
    "dist",
    "transformers",
    "minify.js",
  );

  try {
    await fs.access(minifierPath);
  } catch {
    throw new Error("Minifier not found. Build Workflow/Figma-Context-MCP-DIY to generate dist files.");
  }

  const module = await import(minifierPath);
  if (!module.createMinifiedDesign) {
    throw new Error("createMinifiedDesign export not found in minifier module.");
  }
  return module.createMinifiedDesign as (data: unknown, options?: Record<string, unknown>) => unknown;
}

export const figmaMinifyTask: TaskHandler = async (spec) => {
  if (!spec.figma) {
    throw new Error("spec.figma is required for figma.minify");
  }

  const rawRelative = spec.figma.rawPath ?? spec.output?.raw ?? path.join(spec.output?.dir ?? "figma", "figma-main.yaml");
  const minRelative = spec.figma.minPath ?? spec.output?.min ?? path.join(spec.output?.dir ?? "figma", "figma-main.min.yaml");
  const rawPath = resolvePath(rawRelative);
  const minPath = resolvePath(minRelative);
  await ensureDir(path.dirname(minPath));

  const data = await loadStructuredData(rawPath);
  const createMinifiedDesign = await loadMinifier();
  const minified = createMinifiedDesign(data, {
    keepMetadata: spec.options?.keepMetadata ?? true,
    preserveNodeAnchors: spec.options?.preserveNodeAnchors ?? true,
  });

  let serialized: string;
  try {
    const yaml = await import("yaml");
    serialized = yaml.stringify(minified);
  } catch {
    const jsYaml = await import("js-yaml");
    serialized = jsYaml.dump(minified);
  }
  await fs.writeFile(minPath, serialized, "utf-8");

  return {
    summary: `Minified raw Figma data (${rawRelative} → ${minRelative})`,
    outputPaths: { min: minRelative },
  };
};
